using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using MIMPGameLibrary;
using System.Runtime.Serialization;

namespace MapCreator
{
    public partial class MapCreatorMain : Form
    {
        GameState gameState;

        public MapCreatorMain()
        {
            InitializeComponent();

            foreach (Hex.TerrainType type in Enum.GetValues(typeof(Hex.TerrainType)))
            {
                cmbTerrain.Items.Add(type);
            }
            
            gameState = new GameState(1, 1, 2);
            btnSetMap.Click += UpdateMapItems;
            btnSetMap.Click += UpdateHexItems;
            btnSetHex.Click += UpdateHexItems;
            btnDefaultSettings.Click += UpdateMapItems;
            btnDefaultSettings.Click += UpdateHexItems;
            grpControlPointSettings.TabIndexChanged += UpdateHexItems;
            UpdateMapItems(this, new EventArgs());
            UpdateHexItems(this, new EventArgs());
        }

        private void btnDefaultSettings_Click(object sender, EventArgs e)
        {
            gameState = new GameState(5, 12, 2);
            foreach (Hex h in gameState.Hexes)
            {
                if (h.Col == 0 || h.Col == gameState.Cols - 1)
                {
                    h.Terrain = Hex.TerrainType.Water;
                }
                else if ((h.Row == 3 || h.Row == 4) && (h.Col == 3 || h.Col == 4))
                {
                    h.Terrain = Hex.TerrainType.Mountain;
                }
                else if ((h.Row == 1 || h.Row == 2) && (h.Col == 5 || h.Col == 6))
                {
                    h.Terrain = Hex.TerrainType.Forest;
                }
                else if ((h.Row >= 0 && h.Row <= 2) && (h.Col == 8))
                {
                    h.Terrain = Hex.TerrainType.Tundra;
                }
                else if (h.Row == 4 && h.Col == 7)
                {
                    h.Terrain = Hex.TerrainType.Swamp;
                    h.ControlPoint = new ControlPoint(gameState.ControlPointCount, 3, null);
                    h.ControlPoint.MaxStrength = 3;
                }
                else if (h.Row == 0 && (h.Col == 1 || h.Col == 2))
                {
                    h.Terrain = Hex.TerrainType.Field;
                }
                else if (h.Row == 4 && (h.Col == 10 || h.Col == 9))
                {
                    h.Terrain = Hex.TerrainType.Hills;
                }
            }
            lblMsg.Text = "Generated new map from example.";
        }

        private void btnSaveMap_Click(object sender, EventArgs e)
        {
            if (saveMapDialog.ShowDialog() == DialogResult.OK)
            {
                string mapfile = saveMapDialog.FileName;
                IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                Stream fs = new FileStream(mapfile, FileMode.Create, FileAccess.Write, FileShare.None);
                formatter.Serialize(fs, gameState);
                fs.Close();
                lblMsg.Text = "Saved!" ;
            }
        }

        private void btnSetMap_Click(object sender, EventArgs e)
        {
            GameState gs = new GameState((int)nupRows.Value, (int)nupCols.Value, (int)nupPlayers.Value);
            foreach (Hex h in gameState.Hexes)
            {
                try
                {
                    gs.Hexes[h.Row, h.Col] = h;
                }
                catch (IndexOutOfRangeException)
                {
                    continue;
                }
            }
            gameState = gs;
            lblMsg.Text = "Created new map with specified size and players";
        }

        private void btnSetHex_Click(object sender, EventArgs e)
        {
            foreach (Hex h in gameState.Hexes)
            {
                if(h.Equals((Hex)cmbHex.SelectedItem))
                {
                    h.Terrain = (Hex.TerrainType)cmbTerrain.SelectedItem;
                    if (chkIsControlPoint.Checked)
                    {
                        Player p = cmbInitialController.SelectedIndex == 0 ? null : (Player)cmbInitialController.SelectedItem;
                        h.ControlPoint = new ControlPoint(gameState.ControlPointCount, (int)nupMaxControlStrength.Value, p);
                    }
                    else
                    {
                        h.ControlPoint = null;
                    }
                }
            }
            lblMsg.Text = "Set new Hex stats.";
        }

        private void chkIsControlPoint_CheckedChanged(object sender, EventArgs e)
        {
            grpControlPointSettings.Enabled = chkIsControlPoint.Checked;
        }

        private void cmbHex_SelectedIndexChanged(object sender, EventArgs e)
        {
            Hex curHex = (Hex)cmbHex.SelectedItem;
            cmbTerrain.SelectedItem = curHex.Terrain;
            chkIsControlPoint.Checked = curHex.HasControlPoint;
            if (curHex.HasControlPoint)
            {
                nupMaxControlStrength.Value = curHex.ControlPoint.MaxStrength;
                if (curHex.ControlPoint.Controller != null)
                {
                    cmbInitialController.SelectedItem = curHex.ControlPoint.Controller;
                }
                else
                {
                    cmbInitialController.SelectedItem = "No one";
                }
            }
            else
            {
                cmbInitialController.SelectedItem = null;
                nupMaxControlStrength.Value = 0;
            }
        }

        private void UpdateHexItems(object sender, EventArgs e)
        {
            nupCols.Value = gameState.Cols;
            nupRows.Value = gameState.Rows;
            nupPlayers.Value = gameState.Players.Count;
            int index = cmbHex.SelectedIndex;
            cmbHex.Items.Clear();
            foreach (Hex h in gameState.Hexes)
            {
                cmbHex.Items.Add(h);
            }
            cmbHex.SelectedIndex = index;
        }

        private void UpdateMapItems(object sender, EventArgs e)
        {
            cmbInitialController.Items.Clear();
            cmbInitialController.Items.Add("No one");
            foreach (Player p in gameState.Players)
            {
                cmbInitialController.Items.Add(p);
            }
        }
    }
}